function APIBrowse() {
    let data = {
        filter: PanelFilter(),
        raw_methods: [],
        get methods() {
            let result = data.raw_methods.filter(method_filter);
            return result;
        },
        current: null,
        result: null,
        values: {},
    };
    function params() {
        let result = {};
        for (let index = 0; index < vm.methods[vm.current].params.length; index++) {
            const element = vm.methods[vm.current].params[index];
            result[element.name] = vm.values[element.name];
        }
        return result;
    };
    function method_filter(method) {
        /* Отфильтрованный список */
        let filter = data.filter.data;
        let value = filter.value;
        if ( value.length<1 ) {
            return true;
        }
        if ( method.name.toLowerCase().includes(value.toLowerCase()) ) {
            return true;
        }
        return false;
    };
    function breadcrumbs_render() {
        let result = m('ul', {class: 'breadcrumb mt-3'}, [
            m('li', {class: 'breadcrumb-item'}, m(m.route.Link, {href: '/'}, m('i', {class: 'fa fa-home'}))),
            m('li', {class: 'breadcrumb-item active'}, 'API (JSON-RPC 2.0)'),
        ]);
        return result;
    };
    function method_select(method) {
        data.current = method;
        data.values = {};
        data.result = null;
        for (let index = 0; index < data.current.params.length; index++) {
            const element = data.current.params[index];
            if (element.type==='int') {
                data.values[element.name] = 0;
            }
            if (element.type==='str') {
                data.values[element.name] = "";
            }
        }
    };
    function send() {
        // Добавить нового пользователя
        let params = {};
        for (let index = 0; index < data.current.params.length; index++) {
            const element = data.current.params[index];
            params[element.name] = data.values[element.name];
        }
        console.log(params);
        m.request({
            url: '/api',
            method: "POST",
            body: {
                "jsonrpc": "2.0",
                "method": data.current.name,
                "params": params,
                "id": 1
            }
        }).then(
            function(response) {
                data.result = response;
            }
        );
    };
    function methods_get() {
        m.request({
            url: '/api',
            method: "POST",
            body: {
                "jsonrpc": "2.0",
                "method": "api.methods",
                "id": 1
            }
        }).then(
            function(response) {
                if ('result' in response) {
                    data.raw_methods = response['result'];
                }
            }
        );
    };
    function method_renders(method, methodIdx) {
        let odd = '';
        if (methodIdx % 2) {
            odd = ' bg-light'
        };
        return m('div', {class: 'row'},
            m('div', {class: `col py-2 ${odd}`, onclick: function() {method_select(method)}}, method.name)
            // m('div', {class: `col py-2 ${odd}`, onclick: function() {data.current = method}}, method.name)
        );
    };
    function methods_render() {
        return data.methods.map(method_renders)
    };
    function param_value_render(param) {
        if (param.type==='int') {
            return m('div', {class: 'input-group'},
                m('input', {class: 'form-control', type: 'number', oninput: function (e) {data.values[param.name] = e.target.value}, value: data.values[param.name]})
            )
        } else {
            return m('textarea', {class: 'form-control', oninput: function (e) {data.values[param.name] = e.target.value}, value: data.values[param.name]});
        }
    };
    function param_render(param, paramIdx) {
        let odd = '';
        if (paramIdx % 2) {
            odd = ' bg-light'
        };
        return m('div', {class: 'row'},
            // m('div', {class: `col py-2 ${odd}`, onclick: function() {method_select(method)}}, method.name)
            m('div', {class: `col py-2 ${odd}`}, [
                m('label', `${param.name}: ${param.type}`),
                param_value_render(param),
            ])
        );
    };
    function params_render() {
        return data.current.params.map(param_render)
    };
    function current_render() {
        if (data.current) {
            return m('div', {class: 'col-md-8'}, [
                m('h2', data.current.name),
                m('h3', 'Описание'),
                m('p', data.current.summary),
                m('h3', 'Параметры'),
                params_render(),
                m('h3', 'Возвращаемое значение'),
                m('p', `Тип: ${ data.current.return }`),
                m('h3', 'Пример вызова'),
                m('div', {class: 'card'},
                    m('div', {class: 'card-body'},
                        m('pre', `$ curl -i -X POST \
    -H "Content-Type: application/json; indent=4" \
    -d '{
    "jsonrpc": "2.0",
    "method": "${ data.current.name }",
    "params": { params },
    "id": "1"
}' { request.url_root }api`
                        ),
                    ),
                ),
                m('div', {class: 'row'},
                    m('div', {class: 'col py-2'},
                        m('button', {class: 'btn btn-outline-success btn-lg float-end', type: 'submit', onclick: send}, 'Вызвать'),
                    ),
                ),
                m('div', {class: 'card'},
                    m('div', {class: 'card-body'},
                        m('pre', JSON.stringify(data.result, null, 4 )),
                    ),
                ),
            ])
        }
    };
    return {
        oninit: function(vnode) {
            console.log('APIBrowse.oninit');
            methods_get();
        },
        view: function(vnode) {
            console.log('APIBrowse.view');
            result = [
                breadcrumbs_render(),
                m('div', {class: 'row'},
                    m('div', {class: 'col h1 py-2'}, [
                        m('button', {type: "button", class: "btn btn-outline-secondary btn-lg me-2", onclick: function() { panel_show(data.filter.data) }},
                            m('i', {class: "fa fa-filter"})
                        ),
                        'API (JSON-RPC 2.0)',
                    ])
                ),
                m('hr'),
                m('p', 'Браузер для API (JSON-RPC 2.0) поможет просмотреть список поддерживаемых методов, позволит отправить запросы, получить данные и отобразить результаты.'),
                m(data.filter),
                m('div', {class: 'row', style: 'min-height: 300px;'},
                    m('div', {class: 'col-md-4 overflow-auto position-relative'},
                        m('div', {class: 'position-absolute w-100'},
                            methods_render()
                        ),
                    ),
                    current_render(),
                ),
                breadcrumbs_render(),
            ];
            return result;
        }
    };
};
